#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int SLTDataType;
typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;
//打印链表元素
void SLTPrint(SLTNode* phead)
{
	SLTNode* ptmp = phead;
	while (ptmp)
	{
		printf("%d->", ptmp->data);
		ptmp = ptmp->next;
	}
	printf("NULL\n");
}
//申请新链表节点
SLTNode* SLTBuyNode(SLTDataType x)
{
	SLTNode* pnew = (SLTNode*)malloc(sizeof(SLTNode));
	if (pnew == NULL)
	{
		perror("申请节点失败");
		exit(1);
	}
	pnew->data = x;
	pnew->next = NULL;
	return pnew;
}
//寻找链表尾端的前一个结点
SLTNode** FindTailFront(SLTNode** pphead)
{
	//因为这个函数肯定是在别的函数里被引用的，能进行到这里pphead肯定不为空，就没加断言
	while ((*pphead)->next->next)
	{
		pphead = &((*pphead)->next);
	}
	return pphead;
}
//尾部插入
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* pnew = SLTBuyNode(x);
	if (*pphead && (*pphead)->next)//非单节点链表，需要找尾
	{
		pphead = FindTailFront(pphead);
		(*pphead)->next->next = pnew;
	}
	else if (*pphead == NULL)//空链表，直接赋值
	{
		(*pphead) = pnew;
	}
	else//单节点链表，给next赋值
	{
		(*pphead)->next = pnew;
	}
}
void SListDesTroy(SLTNode** pphead)
{
	assert(pphead);
	while (*pphead)//空链表根本不会进循环，函数不起任何作用，所以断言的时候就不把*pphead也丢进去，判断它是不是空链表了
	{
		assert(pphead);
		SLTNode* next = (*pphead)->next;
		free(*pphead);
		*pphead = next;
	}
}
SLTNode* Reverse(SLTNode* phead)
{
	SLTNode* pcur1 = phead;
	SLTNode* pcur2 = pcur1->next;
	SLTNode* pcur3 = pcur2->next;
	pcur1->next = NULL;
	while (pcur3)
	{
		pcur2->next = pcur1;
		pcur1 = pcur2;
		pcur2 = pcur3;
		pcur3 = pcur3->next;
	}
	pcur2->next = pcur1;
	return pcur2;
}
int main()
{
	//先自己生成一组链表
	//[7, 4, 10, 8, 2, 9, 6, 1 ,3, 5]
	SLTNode* phead = NULL;
	SLTPushBack(&phead, 7);
	SLTPushBack(&phead, 4);
	SLTPushBack(&phead, 10);
	SLTPushBack(&phead, 8);
	SLTPushBack(&phead, 2);
	SLTPushBack(&phead, 9);
	SLTPushBack(&phead, 6);
	SLTPushBack(&phead, 1);
	SLTPushBack(&phead, 3);
	SLTPushBack(&phead, 5);
	SLTPrint(Reverse(phead));
	SListDesTroy(&phead);
	return 0;
}